package com.qfx.modules.common.util;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.InputStreamReader;

/**
 * <h5>描述:执行Windows或和Linux系统命令</h5>
 *  
 */
public class ToolOSCmd {
	
	/**
	 * 字符集格式
	 */
	private static final String CHARSET = getChatSet();
	
	public static void main(String[] args) {
		String result = execCmd("ipconfig");
		if (result.equals("")) {
			System.out.println("执行命令发生错误");
		} else {
			System.out.println(result);
		}
	}
	
	/**
	 * <h5>功能: 执行系统命令, 返回执行结果</h5>
	 * 
	 * @param cmd 需要执行的命令
	 * @return 
	 */
	public static String execCmd(String cmd) {
		StringBuilder result = new StringBuilder();
		
		Process process = null;
		BufferedReader bufrIn = null;
		BufferedReader bufrError = null;
		
		try {
			// 执行命令, 返回一个子进程对象（命令在子进程中执行）
			process = Runtime.getRuntime().exec(cmd);
			
			// 方法阻塞, 等待命令执行完成（成功会返回0）
			int resultCode = process.waitFor();
			if (resultCode == 0 ) {
				if (null == CHARSET) {
					// 获取命令执行结果, 有两个结果: 正常的输出 和 错误的输出（PS: 子进程的输出就是主进程的输入）
					bufrIn = new BufferedReader(new InputStreamReader(process.getInputStream()));
					bufrError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
				} else {
					// 获取命令执行结果, 有两个结果: 正常的输出 和 错误的输出（PS: 子进程的输出就是主进程的输入）
					bufrIn = new BufferedReader(new InputStreamReader(process.getInputStream(), CHARSET));
					bufrError = new BufferedReader(new InputStreamReader(process.getErrorStream(), CHARSET));
				}
				
				// 读取输出
				String line = null;
				while ((line = bufrIn.readLine()) != null) {
					result.append(line).append('\n');
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeStream(bufrIn);
			closeStream(bufrError);
			
			// 销毁子进程
			if (process != null) {
				process.destroy();
			}
		}
		
		// 返回执行结果
		return result.toString();
	}
	
	/**
	 * <h5>功能:执行系统命令, 返回执行结果</h5>
	 * 
	 * @param cmd 需要执行的命令
	 * @param dir 执行命令的子进程的工作目录, null 表示和当前主进程工作目录相同
	 * @return 
	 */
	public static String execCmd(String cmd, File dir) {
		StringBuilder result = new StringBuilder();

		Process process = null;
		BufferedReader bufrIn = null;
		BufferedReader bufrError = null;

		try {
			// 执行命令, 返回一个子进程对象（命令在子进程中执行）
			process = Runtime.getRuntime().exec(cmd, null, dir);

			// 方法阻塞, 等待命令执行完成（成功会返回0）
			int resultCode = process.waitFor();
			if (resultCode == 0 ) {
				if (null == CHARSET) {
					// 获取命令执行结果, 有两个结果: 正常的输出 和 错误的输出（PS: 子进程的输出就是主进程的输入）
					bufrIn = new BufferedReader(new InputStreamReader(process.getInputStream()));
					bufrError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
				} else {
					// 获取命令执行结果, 有两个结果: 正常的输出 和 错误的输出（PS: 子进程的输出就是主进程的输入）
					bufrIn = new BufferedReader(new InputStreamReader(process.getInputStream(), CHARSET));
					bufrError = new BufferedReader(new InputStreamReader(process.getErrorStream(), CHARSET));
				}
				
				// 读取输出
				String line = null;
				while ((line = bufrIn.readLine()) != null) {
					result.append(line).append('\n');
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeStream(bufrIn);
			closeStream(bufrError);

			// 销毁子进程
			if (process != null) {
				process.destroy();
			}
		}

		// 返回执行结果
		return result.toString();
	}
	
	// ==================== private method ====================

	/**
	 * <h5>功能:关闭流并且释放与其相关的任何方法,如果流已被关闭,那么调用此方法没有效果</h5>
	 * 
	 * @param stream 
	 */
	private static void closeStream(Closeable stream) {
		if (stream != null) {
			try {
				stream.close();
			} catch (Exception e) {
				// nothing
			}
		}
	}
	
	/**
	 * <h5>功能:获取系统语言编码,默认GBK</h5>
	 * 	
	 * @return 
	 */
	private static String getChatSet() {
		String charSet = "GBK";
		if (ToolOSInfo.isLinux()) {
			String lang = execCmd("echo $LANG").toLowerCase();
			// zh_CN.UTF8
			if (lang.indexOf("utf8") >= 0) {
				charSet = "UTF-8";
			}
		}
		return charSet;
	}
}
